package com.itheima.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.CustomException;
import com.itheima.common.R;
import com.itheima.domain.*;
import com.itheima.dto.DishDto;
import com.itheima.dto.SetmealDishDto;
import com.itheima.dto.SetmealDto;
import com.itheima.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.lang.management.PlatformManagedObject;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
@Api(tags = "套餐相关接口")
public class SetmealController {
    /**
     * 套餐管理
     */
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private CategoryService categoryService;
    /**
     * 菜品管理
     */
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;


    /**
     * 分页查询信息
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @ApiOperation(value = "套餐信息分页查询")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "page", value = "页码", readOnly = true),
                    @ApiImplicitParam(name = "pageSize", value = "当前页条目数", readOnly = true),
                    @ApiImplicitParam(name = "name", value = "条件", readOnly = true)
            }
    )
    @GetMapping("/page")
    public R<Page> page(Integer page, Integer pageSize, String name) {
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        Page<SetmealDto> dtoPage = new Page<>();
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name != null, Setmeal::getName, name);
        queryWrapper.orderByAsc(Setmeal::getPrice);
        Page<Setmeal> pages = setmealService.page(setmealPage, queryWrapper);
        //对象拷贝
        BeanUtils.copyProperties(pages, dtoPage, "records");//基本分页参数
        List<Setmeal> records = setmealPage.getRecords();
        List<SetmealDto> collect = records.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);//setmeal基本信息
            //分类id
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                setmealDto.setCategoryName(categoryName);
                //将分类信息放到dto里面
            }
            return setmealDto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(collect);
        return R.success(dtoPage);
    }

    /**
     * 套餐添加
     *
     * @param setmealDto
     * @return
     */
    @ApiOperation(value = "套餐添加")
    @CacheEvict(value = "setmealCache", allEntries = true)
    @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto) {

        log.info("套餐添加方法执行:{}", setmealDto);

        setmealService.saveWithDish(setmealDto);
        return R.success("套餐添加成功");
    }

    /**
     * 根据ID查询套餐信息
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "查询单个套餐")
    @ApiImplicitParam(name = "id", value = "套餐id", readOnly = true)
    @GetMapping("/{id}")
    public R<SetmealDto> getById(@PathVariable Long id) {
        Setmeal setmeal = setmealService.getById(id);
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);
        SetmealDto setmealDto = new SetmealDto();
        setmealDto.setSetmealDishes(setmealDishes);
        BeanUtils.copyProperties(setmeal, setmealDto);
        return R.success(setmealDto);
    }

    /**
     * 删除数据
     *
     * @param ids
     * @return
     */
    @ApiOperation(value = "删除套餐")
    @ApiImplicitParam(name = "ids", value = "多套餐id", readOnly = true)
    @CacheEvict(value = "setmealCache", allEntries = true)
    @DeleteMapping
    public R<String> delete(@RequestParam(defaultValue = "-1") List<Long> ids) {
        for (Long id : ids) {
            if (id == -1) {
                throw new CustomException("请勾选需要删除的数据！！！");
            }
        }
        log.info("删除接收id:{}", ids);
        setmealService.removeWithDish(ids);
        return R.success("套餐数据删除成功");
    }

    /**
     * 批量停售
     *
     * @param ids
     * @return
     */
    @ApiOperation(value = "批量停售")
    @ApiImplicitParam(name = "ids", value = "多套餐id", readOnly = true)
    @PostMapping("/status/0")
    public R<String> statusUpdate0(@RequestParam Long[] ids) {
        //遍历数组获取id
        for (Long id : ids) {
            //根据id获取菜品
            Setmeal setmeal = setmealService.getById(id);
            //将状态设置为0停售
            setmeal.setStatus(0);
            //将数据更新到数据库
            setmealService.updateById(setmeal);
        }
//        返回更新成功标志
        return R.success("商品已停售");
    }

    /**
     * 批量启售
     *
     * @param ids
     * @return
     */
    @ApiOperation(value = "批量起售")
    @ApiImplicitParam(name = "ids", value = "批量起售", readOnly = true)
    @PostMapping("/status/1")
    public R<String> statusUpdate1(@RequestParam Long[] ids) {
        //遍历数组获取id
        for (Long id : ids) {
            //根据id获取菜品
            Setmeal setmeal = setmealService.getById(id);
            //将状态设置为0停售
            setmeal.setStatus(1);
            //将数据更新到数据库
            setmealService.updateById(setmeal);
        }
//        返回更新成功标志
        return R.success("商品已停售");
    }

    /**
     * 更新套餐数据
     *
     * @param setmealDto
     * @return
     */
    @ApiOperation(value = "更新套餐")
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto) {
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        Long id = setmealDto.getId();
        setmealDishes.stream().map((item) -> {
            item.setSetmealId(id);
            return item;
        }).collect(Collectors.toList());
        LambdaQueryWrapper<SetmealDish> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(SetmealDish::getSetmealId, id);
        //先删除再添加
        setmealDishService.remove(lambdaQueryWrapper);
        setmealDishService.saveBatch(setmealDishes);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Setmeal::getId, setmealDto.getId());
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDto, setmeal);
        setmealService.updateById(setmeal);
        return R.success("更新成功");

    }

    /**
     * 根据分类信息查询套餐
     *
     * @param setmeal
     * @return
     */
    @ApiOperation(value = "根据分类查询套餐")
    @Cacheable(value = "setmealCache", key = "#setmeal.categoryId+'_'+#setmeal.status")
    @GetMapping("/list")
    public R<List<SetmealDto>> list(Setmeal setmeal) {
//        根据分类id查询当前分类下有多少套餐
        Long categoryId = setmeal.getCategoryId();
        log.info("获取到的分类id:{}", categoryId);

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(categoryId != null, Setmeal::getCategoryId, categoryId);
        List<Setmeal> setmealList = setmealService.list(queryWrapper);
//        遍历每个套餐查询每个套餐菜品关系表
        List<SetmealDto> setmealDtoList = setmealList.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);
            log.info("------------------------------{}", item);
            Long itemId = item.getId();
            LambdaQueryWrapper<SetmealDish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
            dishLambdaQueryWrapper.eq(itemId != null, SetmealDish::getSetmealId, itemId);
            List<SetmealDish> list = setmealDishService.list(dishLambdaQueryWrapper);
            setmealDto.setSetmealDishes(list);
            return setmealDto;
        }).collect(Collectors.toList());
//                查出套餐关系表
        return R.success(setmealDtoList);
    }

    /**
     * 根据套餐id查询套餐内菜品信息
     *
     * @param setmealId
     * @return
     */
    @ApiOperation(value = "查询单个套餐信息")
    @ApiImplicitParam(name = "setmealId", value = "套餐id", readOnly = true)
    @GetMapping("/dish/{setmealId}")
    public R<List<SetmealDishDto>>/*R<SetmealDto>*/ dish(@PathVariable Long setmealId) {
        log.info("套餐id:{}", setmealId);
//        //根据套餐id查询套餐内菜品及口味信息
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(setmealId != null, SetmealDish::getSetmealId, setmealId);
        List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);
        List<SetmealDishDto> collect = setmealDishList.stream().map((item) -> {
            SetmealDishDto setmealDishDto = new SetmealDishDto();
            BeanUtils.copyProperties(item, setmealDishDto);
            //获取每个菜品的图片id
            Long dishId = item.getDishId();
            LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
            dishQueryWrapper.eq(dishId != null, Dish::getId, dishId);
            Dish one = dishService.getOne(dishQueryWrapper);
            String image = one.getImage();
            String description = one.getDescription();
            setmealDishDto.setImage(image);
            setmealDishDto.setDescription(description);
            return setmealDishDto;
        }).collect(Collectors.toList());


//        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(setmealId != null, SetmealDish::getSetmealId, setmealId);
//        List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);
//        List<DishDto> dishDtos = setmealDishList.stream().map((item) -> {//获取每个菜品id
//            //根据每个菜品id获取每个菜品及口味
//            DishDto dishDto = new DishDto();
//            //获取每个菜品
//            LambdaQueryWrapper<Dish> dishLambdaQueryWrapper=new LambdaQueryWrapper<>();
//            dishLambdaQueryWrapper.eq(item.getDishId()!=null,Dish::getId,item.getDishId());
//            Dish dishe = dishService.getOne(dishLambdaQueryWrapper);
//            BeanUtils.copyProperties(dishe,dishDto);
//            //查每个菜品的口味关系
//            LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper=new LambdaQueryWrapper<>();
//            dishFlavorLambdaQueryWrapper.eq(dishe.getId()!=null,DishFlavor::getDishId,dishe.getId());
//            List<DishFlavor> dishFlavors = dishFlavorService.list(dishFlavorLambdaQueryWrapper);
//            dishDto.setFlavors(dishFlavors);
////            再根据每个菜品的信息获取口味信息
//            return dishDto;
//        }).collect(Collectors.toList());

//        Setmeal setmeal = setmealService.getById(setmealId);
//        SetmealDto setmealDto =new SetmealDto();
//        BeanUtils.copyProperties(setmeal,setmealDto);
//
//        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
//        lqw.eq(SetmealDish::getSetmealId,setmealId);
//        List<SetmealDish> dishes = setmealDishService.list(lqw);
//        setmealDto.setSetmealDishes(dishes);
        return R.success(collect);
    }

}
